package com.movie.service;

import com.movie.dto.CommentDTO;
import com.movie.entity.Comment;
import com.movie.entity.Movie;
import com.movie.entity.Review;
import com.movie.entity.User;
import com.movie.repository.CommentRepository;
import com.movie.repository.MovieRepository;
import com.movie.repository.ReviewRepository;
import com.movie.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CommentService {

    private final CommentRepository commentRepository;
    private final MovieRepository movieRepository;
    private final UserRepository userRepository;
    private final ReviewRepository reviewRepository;

    public Page<CommentDTO> findAll(Pageable pageable) {
        return commentRepository.findAll(pageable)
                .map(this::convertToDTO);
    }

    public CommentDTO findById(Long id) {
        Comment comment = commentRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("评论不存在"));
        return convertToDTO(comment);
    }

    @Transactional
    public CommentDTO create(CommentDTO commentDTO) {
        // 验证影片是否存在
        Movie movie = movieRepository.findById(commentDTO.getMovieId())
                .orElseThrow(() -> new RuntimeException("影片不存在"));

        // 验证用户是否存在
        User user = userRepository.findById(commentDTO.getUserId())
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        Comment comment = convertToEntity(commentDTO);
        comment.setMovie(movie);
        comment.setUser(user);

        Comment saved = commentRepository.save(comment);
        return convertToDTO(saved);
    }

    @Transactional
    public CommentDTO update(Long id, CommentDTO commentDTO) {
        Comment existing = commentRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("评论不存在"));

        BeanUtils.copyProperties(commentDTO, existing, "id", "movie", "user", "createdAt", "updatedAt");
        Comment updated = commentRepository.save(existing);
        return convertToDTO(updated);
    }

    @Transactional
    public void delete(Long id) {
        Comment comment = commentRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("评论不存在"));
        commentRepository.delete(comment);
    }

    public Page<CommentDTO> findByMovieId(Long movieId, Pageable pageable) {
        return commentRepository.findByMovieId(movieId, pageable)
                .map(this::convertToDTO);
    }

    public Page<CommentDTO> findByUserId(Long userId, Pageable pageable) {
        return commentRepository.findByUserId(userId, pageable)
                .map(this::convertToDTO);
    }

    public Page<CommentDTO> findByMovieIdAndReviewStatus(Long movieId, String status, Pageable pageable) {
        // 获取指定影片的所有评论
        Page<Comment> comments = commentRepository.findByMovieId(movieId, pageable);

        // 如果状态为空，返回所有评论
        if (status == null || status.isEmpty()) {
            return comments.map(this::convertToDTO);
        }

        // 批量查询审核状态，避免 N+1 查询
        List<Long> commentIds = comments.getContent().stream()
                .map(Comment::getId)
                .collect(Collectors.toList());

        List<Review> reviews = reviewRepository.findByCommentIds(commentIds);
        java.util.Map<Long, String> reviewStatusMap = reviews.stream()
                .collect(Collectors.toMap(r -> r.getComment().getId(), Review::getStatus, (s1, s2) -> s1));

        // 根据审核状态筛选评论（无审核记录默认为 pending）
        List<CommentDTO> filteredComments = comments.getContent().stream()
                .filter(c -> {
                    String s = reviewStatusMap.getOrDefault(c.getId(), "pending");
                    return status.equals(s);
                })
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        // 返回筛选后的评论列表（保持分页参数，total 使用当前筛选数量）
        return new org.springframework.data.domain.PageImpl<>(filteredComments, pageable, filteredComments.size());
    }

    private CommentDTO convertToDTO(Comment comment) {
        CommentDTO dto = new CommentDTO();
        BeanUtils.copyProperties(comment, dto);

        if (comment.getMovie() != null) {
            dto.setMovieId(comment.getMovie().getId());
            dto.setMovieTitle(comment.getMovie().getTitle());
        }

        if (comment.getUser() != null) {
            dto.setUserId(comment.getUser().getId());
            dto.setUserName(comment.getUser().getUsername());
        }

        return dto;
    }

    private Comment convertToEntity(CommentDTO dto) {
        Comment comment = new Comment();
        BeanUtils.copyProperties(dto, comment);
        return comment;
    }
}